package com.sunwayhorizo.health.platform.security.login;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.patad.empi.PatientBaseInfoDTO;
import com.sunwayhorizo.health.business.dto.registries.DepartmentDTO;
import com.sunwayhorizo.health.business.dto.registries.OrganizationDTO;
import com.sunwayhorizo.health.business.dto.security.SecurityAuthenticatorDTO;
import com.sunwayhorizo.health.business.integration.securityI.SecurityInterfaceWrapManagerLocal;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.platform.security.persistent.SecurityAccount;
import com.sunwayhorizo.health.platform.security.persistent.SecurityAccountRole;
import com.sunwayhorizo.health.platform.security.persistent.SecurityResource;
import com.sunwayhorizo.health.platform.security.persistent.SecurityRole;
import com.sunwayhorizo.health.platform.security.service.dataInit.SecurityDataInitManagerLocal;
import com.sunwayhorizo.health.platform.security.service.identity.SecurityAccountManagerLocal;
import com.sunwayhorizo.health.platform.security.service.permission.SecurityResourceManagerLocal;
import com.sunwayhorizo.health.platform.util.PropertiesUtil;

@Name("AuthenticatorManager")
@Stateless
@SuppressWarnings("unchecked")
public class AuthenticatorManager implements AuthenticatorManagerLocal
{
    public ResultsDTO securityAuthenticate(SecurityAccount account) throws Hl7Exception
    {
        SecurityAccountManagerLocal accountManager = (SecurityAccountManagerLocal) Component.getInstance("SecurityAccountManager");
        ResultsDTO dto = accountManager.findLoginSecurityAccountByAccountNameAndPWD(account);
        if( !dto.getResultFlag() ){
            if( (SecurityAccount)dto.getObject() == null ){
                if(isSystemAccount(account.getAccountName(),account.getPassword())){
                    try{
                        initDataOfSystemAccount();
                        dto = accountManager.findLoginSecurityAccountByAccountNameAndPWD(account);
                    }catch(Exception e){
                        e.printStackTrace();
                        dto.setResultDesc("初始化数据失败");
                        dto.setResultFlag(false);
                        return dto;
                    }
                }else{
                    return dto;
                }
            }else{
                return dto;
            }
        }
        SecurityAuthenticatorDTO resultDTO = new SecurityAuthenticatorDTO();
        
        SecurityAccount dbAccount = (SecurityAccount)dto.getObject();
        /**
         * 组装account，roles和resources
         */
        resultDTO.setSecurityAccount(dbAccount);
        List<SecurityRole> roles = new ArrayList<SecurityRole>();
        for( SecurityAccountRole ar : dbAccount.getAccountRoles() ){
            roles.add(ar.getRole());
        }
        resultDTO.setSecurityRoles(roles);
        
        SecurityResourceManagerLocal resourceManager = (SecurityResourceManagerLocal) Component.getInstance("SecurityResourceManager");
        List<SecurityResource> rootResource = (List<SecurityResource>)resourceManager.findSecurityResourceTreeByAccountIdJoinRoleWithScreen(dbAccount.getAccountId()).getObject();
        if( rootResource !=null ){
            resultDTO.setResources(rootResource.get(0).getChildren());
        }
        
        if( !isSystemAccount(account.getAccountName(),account.getPassword()) ){
            SecurityInterfaceWrapManagerLocal wrapManager= (SecurityInterfaceWrapManagerLocal) Component.getInstance("SecurityInterfaceWrapManager");
            
            String orgCode = dbAccount.getOrgCode();
            String deptCode = dbAccount.getDeptCode();
            String empCode = dbAccount.getEmpCode();
            
            OrganizationDTO orgDTO = null;
            if( StrUtil.isNotEmpty(orgCode) ){
                try{
                    orgDTO = wrapManager.findOrganizationByCode(orgCode);
                }catch(Exception e){
                    System.out.println( e.getMessage() );
                }
            }
    
            DepartmentDTO departDTO = null;
            if( StrUtil.isNotEmpty(deptCode) ){
                try{
                    departDTO = wrapManager.findDepartmentByCode(deptCode);
                }catch(Exception e){
                    System.out.println( e.getMessage() );
                }
            }
            
            PatientBaseInfoDTO userDTO = null;
            if( StrUtil.isNotEmpty(empCode) ){
                try{
                    userDTO = wrapManager.findEmployeeByCode(empCode);
                }catch(Exception e){
                    System.out.println( e.getMessage() );
                }
            }
            
            List<DepartmentDTO> workGroupList = null;
            if( StrUtil.isNotEmpty(empCode) ){
                try{
                    workGroupList = wrapManager.findWorkGroupListByEmployeeCode(empCode);
                }catch(Exception e){
                    System.out.println( e.getMessage() );
                }
            }
            
            if( orgDTO != null )
            {
                resultDTO.setOrganization(orgDTO);
            }
            
            if( departDTO != null )
            {
                resultDTO.setDepartment(departDTO);
            }
            
            if( userDTO != null )
            {
                resultDTO.setUser(userDTO);
            }
            
            if( ListUtil.isNotEmpty(workGroupList)){
                resultDTO.setWorkgroups(workGroupList);
            }
        }
        ResultsDTO finalDTO = new ResultsDTO();
        finalDTO.setResultDesc("验证通过！");
        finalDTO.setResultFlag(true);
        finalDTO.setObject(resultDTO);
        return finalDTO;
    }
    
    private boolean isSystemAccount( String accountName,String password ){
        Properties p = PropertiesUtil.instance().getProperties();
        final String SYSTEM_ACCOUNT_NAME = p.getProperty("system.userName");
        final String SYSTEM_ACCOUNT_PWD = p.getProperty("system.password");
        if( StrUtil.isNotEmpty(SYSTEM_ACCOUNT_NAME) && StrUtil.isNotEmpty(SYSTEM_ACCOUNT_PWD) && SYSTEM_ACCOUNT_NAME.equals(accountName) && SYSTEM_ACCOUNT_PWD.equals(password) ){
            return true;
        }else{
            return false;
        }
    }
    
    private void initDataOfSystemAccount() throws IOException{
        Properties p = PropertiesUtil.instance().getProperties();
        String size = (String)p.getProperty("sql.key.size");
        List<String> sqlLineList = new ArrayList<String>();
        for(int i=1;i<=Integer.valueOf(size);i++ ){
            String value = p.getProperty("sql.key"+i);
            sqlLineList.add(value);
        }
        System.out.println( "初始化数量 "+ sqlLineList.size() );
        SecurityDataInitManagerLocal dataInitManager = (SecurityDataInitManagerLocal) Component.getInstance("SecurityDataInitManager");
        dataInitManager.executeSQL(sqlLineList);
    }
}
